package com.dex4d.ui.wallet.fragment;

import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;

import com.dex4d.R;
import com.dex4d.constants.AppConstants;
import com.dex4d.constants.IConstants;
import com.dex4d.core.AppToolBarBaseActivity;
import com.dex4d.core.AppToolbarBaseFragment;
import com.dex4d.core.CustomApplication;
import com.dex4d.core.ITabFragment;
import com.dex4d.core.http.DefaultTransformer;
import com.dex4d.core.http.JsonApiWrapper;
import com.dex4d.core.subscribers.ProgressSubscriber;
import com.dex4d.glide.GlideUtil;
import com.dex4d.model.AssetModel;
import com.dex4d.model.HttpResult;
import com.dex4d.model.MarketPriceModel;
import com.dex4d.model.RequestParam;
import com.dex4d.model.User;
import com.dex4d.ui.main.model.TokenContract;
import com.dex4d.ui.wallet.activity.WalletReceiveActivity;
import com.dex4d.ui.wallet.activity.WalletSendActivity;
import com.dex4d.ui.wallet.activity.WalletTxActivity;
import com.dex4d.utils.Arith;
import com.dex4d.utils.BaseUtils;
import com.dex4d.utils.SPUtil;
import com.zhy.adapter.recyclerview.CommonAdapter;
import com.zhy.adapter.recyclerview.base.ViewHolder;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import butterknife.BindView;
import butterknife.OnClick;

/**
 * Created by chengyuchun on 2018/10/23.
 */
public class TabWalletFragment extends AppToolbarBaseFragment implements ITabFragment {
    @BindView(R.id.rv_asset)
    RecyclerView mRvAsset;

    @BindView(R.id.btn_send)
    Button mBtnSend;

    @BindView(R.id.swipe_refresh_layout)
    SwipeRefreshLayout mSwipeRefreshLayout;

    @BindView(R.id.checkbox_asset_show)
    CheckBox mCheckboxAssetShow;

    @BindView(R.id.tv_total_balance)
    TextView mTVtotalBalance;

    @BindView(R.id.tv_currency_type)
    TextView mTvCurrencyType;

    private String mTotalAsset = "0.00";
    private CommonAdapter mCommonAdapter;
    private final static String KEY_TOTAL_ASSET = "KEY_TOTAL_ASSET";
    private List<AssetModel> mAssetList = new ArrayList<AssetModel>();
    private Map<String,AssetModel> mAssetModelMap = new HashMap<String,AssetModel>();
    @Override
    protected int getLayoutId() {
        return R.layout.fragment_tab_wallet;
    }

    @Override
    protected void initVariables() {
        //应测试要求，去掉下拉刷新，改为每5秒自动刷新
        mSwipeRefreshLayout.setEnabled(false);
//        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
//            @Override
//            public void onRefresh() {
//                new Handler().postDelayed(new Runnable() {//模拟耗时操作
//                    @Override
//                    public void run() {
//                        mSwipeRefreshLayout.setRefreshing(false);//取消刷新
//
//                        refreshToken();
//                    }
//                },1500);
//            }
//        });
        mTvCurrencyType.setText(getString(R.string.total_asset,SPUtil.getString(AppConstants.SP_CURRENCY_KEY,"USD").toUpperCase()));


        mCommonAdapter = new CommonAdapter<AssetModel>(mContext, R.layout.item_asset_token, mAssetList) {
            @Override
            protected void convert(ViewHolder holder, final AssetModel assetModel, int position) {
                GlideUtil.displayImg((ImageView) holder.getView(R.id.img_token_logo),assetModel.picUrl);
                holder.setText(R.id.tv_token_name, assetModel.symbol.toUpperCase());
                if(mCheckboxAssetShow.isChecked()){
                    holder.setText(R.id.tv_balance, "******");
                }else {
                    holder.setText(R.id.tv_balance, assetModel.balance);
                }
            }
        };
        mRvAsset.setLayoutManager(new LinearLayoutManager(mContext));
        mRvAsset.setAdapter(mCommonAdapter);
    }

    Handler mHandler=new Handler();
    Runnable runnable=new Runnable() {
        @Override
        public void run() {
            refreshToken();
            mHandler.postDelayed(this, 20000);
        }
    };

    @Override
    protected void loadData() {
        //mTotalAsset = SPUtil.getString(KEY_TOTAL_ASSET);
        mHandler.post(runnable);
    }

    private void refreshToken(){
        //请求此接口获取token列表
        final RequestParam requestParam = new RequestParam();
        requestParam.setId(1);
        requestParam.setJsonrpc(IConstants.JSON_RPC_VERSION);
        requestParam.setMethod(IConstants.GATEWAY_GETTOKENTABLES);
        requestParam.setParams(new ArrayList<String>());

        JsonApiWrapper
                .serviceApi()
                .getTokenTables(requestParam)
                .compose(new DefaultTransformer<HttpResult<List<TokenContract>>>())
                .subscribe(new ProgressSubscriber<HttpResult<List<TokenContract>>>(mContext, false) {
                    @Override
                    public void onNext(HttpResult<List<TokenContract>> result) {
                        mAssetList.clear();
                        //获得Token列表
                        for (TokenContract temp : result.getResult()) {
                            //mAssetModelMap 里的assetModel缓存了余额信息
                            if(mAssetModelMap.get(temp.name)!=null){
                                AssetModel assetModel = mAssetModelMap.get(temp.name);
                                assetModel.contracAddress = temp.token_addr;
                                assetModel.picUrl = temp.icon_app;
                                mAssetList.add(assetModel);
                            }else {
                                AssetModel assetModel = new AssetModel();
                                assetModel.address = User.getInstance().getAddress();
                                assetModel.symbol = temp.name;
                                assetModel.contracAddress = temp.token_addr;
                                assetModel.picUrl = temp.icon_app;
                                //assetModel.balance = "0.0";
                                mAssetList.add(assetModel);
                            }
                        }

                        //刷新余额信息
                        refreshBalanceData(mAssetList);

                        //刷新总资产信息
                        refreshTotalAssetDelay(mAssetList);
                    }
                });
    }

    private RequestParam obtainBalanceRequest(AssetModel assetModel){
        RequestParam requestParam = new RequestParam();
        requestParam.setId(assetModel.id);
        requestParam.setJsonrpc(IConstants.JSON_RPC_VERSION);
        if(IConstants.ETH_SYMBOL.equalsIgnoreCase((assetModel.symbol))){
            //查询以太余额调用此接口
            requestParam.setMethod(IConstants.CONTRACTSERVICE_GETBALANCE);
            requestParam.setParams(Collections.singletonList(assetModel.address));
        }else {
            //查询其他代币余额调用此接口
            requestParam.setMethod(IConstants.CONTRACTSERVICE_ERC20BALANCE);
            List<String> paramsList = new ArrayList<String>();
            paramsList.add(assetModel.contracAddress);
            paramsList.add(assetModel.address);
            requestParam.setParams(paramsList);
        }
        return requestParam;
    }

    private void refreshTotalAssetDelay(final List<AssetModel> assetList){
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                refreshTotalAsset(assetList);
            }
        },300);
    }

    private void refreshTotalAsset(final List<AssetModel> assetList){
        List<String> tokenNameList = new ArrayList<>();
        for(AssetModel assetModel:assetList){
            tokenNameList.add(assetModel.symbol.toLowerCase());
        }

        List paramList = new ArrayList();
        paramList.add(SPUtil.getString(AppConstants.SP_CURRENCY_KEY,"usd").toLowerCase());
        paramList.add(tokenNameList);

        RequestParam requestParam = new RequestParam();
        requestParam.setId(tokenNameList.size()+1);
        requestParam.setJsonrpc(IConstants.JSON_RPC_VERSION);

        //获取二级市场法币价格
        requestParam.setMethod(IConstants.GATEWAY_GETMARKETPRICE);
        requestParam.setParams(paramList);

        JsonApiWrapper
                .serviceApi()
                .requestMarketPrice(requestParam)
                .compose(new DefaultTransformer<HttpResult<MarketPriceModel>>())  //取网络数据这个函数不能少，这是线程切换
                .subscribe(new ProgressSubscriber<HttpResult<MarketPriceModel>>(mContext, false) {
                    @Override
                    public void onNext(HttpResult<MarketPriceModel> result) {
                        //更新货币类型
                        mTvCurrencyType.setText(getString(R.string.total_asset,SPUtil.getString(AppConstants.SP_CURRENCY_KEY,"USD").toUpperCase()));

                        //更新货币总余额
                        mTotalAsset = calculateTotalBalance(result.getResult(),assetList);
                        SPUtil.putString(KEY_TOTAL_ASSET,mTotalAsset);
                        setTotalAsset(mTotalAsset);
                    }});
    }

    //设置总资产
    private void setTotalAsset(String totalAsset){
        String currencyType = SPUtil.getString(AppConstants.SP_CURRENCY_KEY,"usd").toLowerCase();
        if("usd".equalsIgnoreCase(currencyType)){
            mTVtotalBalance.setText("$"+totalAsset);
        }else {
            mTVtotalBalance.setText("￥"+totalAsset);
        }
    }

    //根据资产数量和市场价格计算总资产
    private String calculateTotalBalance(MarketPriceModel marketPriceModel,List<AssetModel> assetList){
        double total = 0.0;
        for(AssetModel assetModel:assetList){
            if(assetModel.symbol.equalsIgnoreCase("eth")){
                double funds = Arith.mul(Double.parseDouble(assetModel.balance),marketPriceModel.getEth());
                total = Arith.add(total,funds);
            }else if(assetModel.symbol.equalsIgnoreCase("seele")){
                double funds = Arith.mul(Double.parseDouble(assetModel.balance),marketPriceModel.getSeele());
                total = Arith.add(total,funds);
            }else if(assetModel.symbol.equalsIgnoreCase("omg")){
                double funds = Arith.mul(Double.parseDouble(assetModel.balance),marketPriceModel.getOmg());
                total = Arith.add(total,funds);
            }else if(assetModel.symbol.equalsIgnoreCase("zrx")){
                double funds = Arith.mul(Double.parseDouble(assetModel.balance),marketPriceModel.getZrx());
                total = Arith.add(total,funds);
            }
        }
        return new BigDecimal(total).setScale(2,RoundingMode.CEILING).toString();
    }

    private void refreshBalanceData(List<AssetModel> assetList){
        for(int i=0;i < assetList.size();i++){
            final AssetModel assetModel = assetList.get(i);
            JsonApiWrapper
                    .serviceApi()
                    .requestByParam(obtainBalanceRequest(assetModel))
                    .compose(new DefaultTransformer<HttpResult<String>>())  //取网络数据这个函数不能少，这是线程切换
                    .subscribe(new ProgressSubscriber<HttpResult<String>>(mContext, false) {
                        @Override
                        public void onNext(HttpResult<String> result) {
                            String balance = BaseUtils.hexToEtherUnit(result.getResult()); //unit ether
                            if(!balance.equals(assetModel.balance)){
                                assetModel.balance = balance;
                                mCommonAdapter.notifyDataSetChanged();
                                //缓存余额信息
                                mAssetModelMap.put(assetModel.symbol,assetModel);
                            }
                            //更新数据库
                            //updateDatabase(assetModel);
                        }});
        }
    }

    private void updateDatabase(final AssetModel assetModel){
        new Thread(new Runnable() {
            @Override
            public void run() {
                CustomApplication.getDb().assetDao().update(assetModel);
            }
        }).start();
    }

    @Override
    public void onMenuItemClick() {

    }

    @Override
    public Fragment getFragment() {
        return this;
    }

    @Override
    public String getTitle() {
        return null;
    }

    @Override
    protected void initToolbar(AppToolBarBaseActivity mContent) {
        super.initToolbar(mContent);
        mContent.showTitle(getString(R.string.address) + ":" + BaseUtils.formatAddress(User.getInstance().getAddress()));
        mContent.hideBackView();
        mContent.getToolbarRight().setVisibility(View.GONE);
    }

    @OnClick({R.id.btn_send,R.id.btn_receive,R.id.btn_history,R.id.checkbox_asset_show})
    public void onViewClick(View view){
        switch (view.getId()) {
            case R.id.btn_send:
                WalletSendActivity.start(getActivity());
                break;
            case R.id.btn_receive:
                WalletReceiveActivity.start(getActivity());
                break;
            case R.id.checkbox_asset_show:
                if(mCheckboxAssetShow.isChecked()){
                    mCheckboxAssetShow.setBackgroundResource(R.drawable.ic_wallet_hide);
                    mTVtotalBalance.setText("******");
                    mCommonAdapter.notifyDataSetChanged();
                }else {
                    setTotalAsset(mTotalAsset);
                    mCommonAdapter.notifyDataSetChanged();
                    mCheckboxAssetShow.setBackgroundResource(R.drawable.ic_wallet_show);
                }
                break;
            case  R.id.btn_history:
                WalletTxActivity.start(getActivity());
                break;
        }
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if(!hidden){
            refreshToken();
        }
    }

    @Override
    public void onDestroy() {
        mHandler.removeCallbacks(runnable);
        super.onDestroy();
    }
}
